use anyhow::Error;
use crate::{db::Db, frame::Frame};

#[derive(Debug)]
pub struct Delete {
    collection_name: String,
    id: String,
}

impl Delete {
    pub fn parse_from_frame(frame: Frame) -> Result<Self, Error> {
        let mut args = frame.get_args().into_iter();
        
        // Skip command name
        args.next().ok_or_else(|| Error::msg("Missing command"))?;

        let collection_name = args.next().ok_or_else(|| Error::msg("Missing collection name"))?;
        let id = args.next().ok_or_else(|| Error::msg("Missing ID"))?;

        // Ensure no extra arguments
        if let Some(unexpected_arg) = args.next() {
            return Err(Error::msg(
                format!("Unexpected argument: {}", unexpected_arg)
            ));
        }

        Ok(Self {
            collection_name,
            id,
        })
    }

    pub fn apply(self, db: &mut Db) -> Result<Frame, Error> {
        let collection = db.collections.get_mut(&self.collection_name)
            .ok_or_else(|| Error::msg(
                format!("Collection '{}' does not exist", self.collection_name)
            ))?;

        if !collection.vectors.contains_key(&self.id) {
            return Err(Error::msg(
                format!("ID '{}' does not exist in collection '{}'", self.id, self.collection_name)
            ));
        }

        collection.vectors.remove(&self.id);
        Ok(Frame::Ok)
    }
}